<template>
  <main class="main_box" id="app">
    <h4 class="headline">图片处理</h4>
    <div class="work-space">
      <div class="work-space-navigation">
        <ul class="work-tools-list">
          <li class="work-tool-item">
            <p class="work-tool-name">属性修改</p>
            <div class="work-tool-content tool-modify-attr">
              <p>
                <span class="tool-name-text">图片格式：</span>
                <select class="selectpicker" data-width="80px" @change="saveStep" v-model="imgHandleParam.format">
                  <option value="">原格式</option>
                  <option value="jpg">jpg</option>
                  <option value="gif">gif</option>
                  <option value="png">png</option>
                </select>
                <button type="button" class="btn btn-default" @click="cropHandle">裁剪</button>
              </p>
              <p class="tool-margin-top">
                <span class="tool-name-text">旋转操作：</span>
                <button type="button" class="iconfont icon-xuanzhuan-fan counterclockwise" @click="imgHandleParam.rotate === -345 ? imgHandleParam.rotate = 0 : imgHandleParam.rotate -= 15" title="逆时针旋转" data-toggle="tooltip"></button>
                <button type="button" class="iconfont icon-xuanzhuan-copy clockwise" @click="imgHandleParam.rotate === 345 ? imgHandleParam.rotate = 0 : imgHandleParam.rotate += 15" title="顺时针旋转" data-toggle="tooltip"></button>
                <button type="button" class="iconfont icon-fanzhuan horizontal-flip" title="水平翻转"></button>
                <button type="button" class="iconfont icon-fanzhuan-copy vertical-flip" title="垂直翻转"></button>
              </p>
            </div>
          </li>
          <li class="work-tool-item">
            <p class="work-tool-name">修改尺寸</p>
            <div class="work-tool-content modify-size">
              <p class="text">
                <span>{{ rangeParam.min }}%</span>
                <span class="pull-right">{{ rangeParam.max }}%</span>
              </p>
              <slider v-model="imgZoom" @on-change="rangeChangeHandle" :min="rangeParam.min" :max="rangeParam.max" :step="1" show-tip="never"/>
              <p class="current-range">缩放比：{{ imgZoom }}%</p>
              <div class="custom-size">
                <div class="size-input">
                  <p>自定义高：</p>
                  <input v-model.number.trim="imgInfo.height" maxlength="4" type="text" @change="customHeightOrWidth" class="form-control"/>
                </div>
                <span class="tool-lock-scale">
                  <span class="iconfont icon-lianjie1" :class="{ 'active': !lockScale }" @click="lockScale = !lockScale" title="锁定比例" data-toggle="tooltip"></span>
                </span>
                <div class="size-input">
                  <p>自定义宽：</p>
                  <input v-model.number.trim="imgInfo.width" maxlength="4" @change="customHeightOrWidth" type="text" class="form-control"/>
                </div>
              </div>
            </div>
          </li>
          <li class="work-tool-item">
            <p class="work-tool-name">图片压缩</p>
            <div class="work-tool-content image-compress">
              <p>图片品质：</p>
              <p class="text"><span>1</span> <span class="pull-right">100</span></p>
              <slider v-model="quality" @on-change="qualityChangeHandle" :min="qualityParam.min" :max="qualityParam.max" :step="1" show-tip="never"/>
              <p>
                <span v-html="qualityText"></span>
                <span class="pull-right">{{ imageSize }}</span>
              </p>
            </div>
          </li>
        </ul>
        <div class="wrapper" v-show="!imgUrl" @click="warning"></div>
      </div>
      <div class="work-space-image-area">
        <div class="file-drag-area" v-show="!currentImg" :class="{'drag-in': dragIn}" @dragenter="dragIn = true" @dragleave="dragIn = false">
          <button type="button" class="btn btn-bigwe" id="image-handle-upload">选择图片</button>
        </div>
        <div class="image-edit-area" v-show="imgUrl">
          <img @load="loadFinish" :src="currentImg" alt="" id="cropper-img" :class="{'not-crop': !isCropping}">
        </div>
      </div>
    </div>
    <div class="img-handle-control-btns">
      <button type="button" class="btn btn-success" :disabled="!imgUrl">保存</button>
      <button type="button" class="btn btn-default" @click="resetImage" :disabled="!imgUrl">重置</button>
      <button type="button" class="btn btn-default" :disabled="operateQueue.length === 0" @click="prevStepHandle">上一步</button>
    </div>
  </main>
</template>
<script>
/** 范围选择插件 */
import 'cropper/dist/cropper.css';
import 'cropper';
import 'iview/dist/styles/iview.css';
import 'qiniu';
import slider from 'iview/src/components/slider';
import message from 'message';
import Vue from 'vue';
import {
  FILEUPLOAD
} from 'api';
import constants from 'constants';

let {
  showTime
} = message;

let paramFormat = {
    format( key, value ) {
      return value && `/${key}/${value}`;
    },
    thumbnail( key, value ) {
      if ( typeof value === 'number' ) {
        return value === 100 ? '' : `/${key}/!${value}p`;
      } else {
        return `/${key}/${value.width}x${value.height}!`;
      }
    },
    rotate( key, value ) {
      return value === 0 ? '' : `/${key}/${value}`;
    },
    crop( key, value ) {
      return !value ? '' : `/${key}/!${Math.round(value.width)}x${Math.round(value.height)}a${Math.round(value.x)}a${Math.round(value.y)}`;
    },
    quality( key, value ) {
      return value === 100 ? '' : `/${key}/${value}`;
    }
  },
  initImageParam = {
    format: '',
    thumbnail: 100,
    rotate: 0,
    crop: null,
    quality: 100
  };
export default {
  data() {
    return {
      lockScale: true,
      dragIn: false,
      isCropping: false,
      imgZoom: 100,
      quality: 100,
      imgUrl: '',
      catchCrop: null,
      rangeParam: {
        min: 25,
        max: 100,
      },
      qualityParam: {
        min: 1,
        max: 100,
      },
      imgHandleParam: Object.assign( {}, initImageParam ),
      operateQueue: [],
      imgInfo: {
        size: 0
      },
      imageInitInfo: null, // 图片的初始信息
      scale: 0
    };
  },
  watch: {
    imgHandleParam: {
      handler() {
        this.getImgInfo();
      },
      deep: true
    },
    'imgInfo.width' ( val ) {
      this.imgInfo.height = this.lockScale ? Math.round( val / this.scale ) : this.imgInfo.height;
    },
    'imgInfo.height' ( val ) {
      this.imgInfo.width = this.lockScale ? Math.round( val * this.scale ) : this.imgInfo.width;
    }
  },
  computed: {
    imageSize() {
      if ( isNaN( this.imgInfo.size ) || this.imgInfo.size === 0 ) {
        return '';
      }
      if ( this.imgInfo.size < 1024 ) {
        return `${this.imgInfo.size.toFixed(1)}b`;
      } else if ( this.imgInfo.size >= 1024 && this.imgInfo.size < 1048576 ) {
        return `${(this.imgInfo.size/1024).toFixed(1)}kb`
      } else {
        return `${(this.imgInfo.size/1024/1024).toFixed(1)}Mb`
      }
    },
    currentImg() {
      let qiniuParam = '';
      if ( this.isParamChange() ) {
        qiniuParam = '?imageMogr2/interlace/1'
        for ( let i in this.imgHandleParam ) {
          qiniuParam += paramFormat[ i ].call( this, i, this.imgHandleParam[ i ] );
        }
      }
      return `${this.imgUrl}${qiniuParam}`;
    },
    qualityText() {
      if ( this.quality < 21 ) {
        return '<span class="bad">差</span>';
      } else if ( this.quality >= 21 && this.quality < 41 ) {
        return '<span class="bad">中</span>';
      } else if ( this.quality >= 41 && this.quality < 61 ) {
        return '良';
      } else if ( this.quality >= 61 && this.quality < 81 ) {
        return '<span class="excellent">优</span>';
      } else {
        return '<span class="excellent">最佳</span>';
      }
    }
  },
  methods: {
    customHeightOrWidth() {
      if ( this.imgInfo.width > this.imageInitInfo.width || this.imgInfo.height > this.imageInitInfo.height ) {
        this.imgHandleParam.thumbnail = Object.assign( {}, this.imageInitInfo );
        message.showWarning( '已超出图片最大宽高', showTime );
      } else {
        this.imgHandleParam.thumbnail = Object.assign( {}, this.imgInfo );
        this.saveStep();
      }
      this.imgZoom = 100;
    },
    warning() {
      return message.showWarning( '请先上传一张图片', showTime );
    },
    getImgInfo() {
      this.currentImg && $.ajax( `${this.currentImg}${this.currentImg.indexOf( '?' ) !== -1 ? '|': '?'}imageInfo` ).then( ( res ) => {
        this.imgInfo = Object.assign( {}, res );
        !this.imageInitInfo && ( this.imageInitInfo = Object.assign( {}, res ) );
        !this.scale && ( this.scale = res.width / res.height );
      } );
    },
    resetImage() {
      this.imgHandleParam = Object.assign( {}, initImageParam );
    },
    qualityChangeHandle( value ) {
      this.imgHandleParam.quality = value;
      this.saveStep();
    },
    rangeChangeHandle( value ) {
      this.imgHandleParam.thumbnail = value;
      this.saveStep();
    },
    prevStepHandle() {
      this.isNotPrevStatus && this.operateQueue.pop();
      this.isNotPrevStatus = false;
      let operateQueue = this.operateQueue.pop() || Object.assign( {}, initImageParam );
      this.imgHandleParam = operateQueue;

      this.imgZoom = operateQueue.thumbnail;
      this.quality = operateQueue.quality;
      Vue.nextTick( () => $( '.selectpicker', this.$el ).selectpicker( 'refresh' ) )
    },
    saveStep() {
      this.isNotPrevStatus = true;
      this.operateQueue.push( Object.assign( {}, this.imgHandleParam ) );
    },
    isParamChange() {
      return this.imgHandleParam.format !== '' ||
        this.imgHandleParam.thumbnail !== 100 ||
        this.imgHandleParam.rotate !== 0 ||
        this.imgHandleParam.crop !== null ||
        this.imgHandleParam.quality !== 100;
    },
    loadFinish( e ) {

    },
    cropHandle() {
      this.isCropping = !this.isCropping;
      // cropper
      this.$cropperImg = $( '#cropper-img', this.$el ).cropper( this.isCropping ? {
        viewMode: 2,
        crop: ( e ) => {
          /* let prevCrop = this.catchCrop || {};
          this.catchCrop = {
            x: Math.round( e.x + ( prevCrop.x || 0 ) ),
            y: Math.round( e.y + ( prevCrop.y || 0 ) ),
            width: Math.round( e.width + ( prevCrop.width || 0 ) ),
            height: Math.round( e.height + ( prevCrop.height || 0 ) )
          }; */
        },
        ready: () => {
          $( '.cropper-crop-box', this.$el ).append(
            '<div class="crop-controll">\
              <button id="crop-sure" type="button" class="btn">确定</button><button id="crop-cancel" type="button" class="btn">取消</button>\
            </div>'
          );
        }
      } : 'destroy' );
    },
    qiniuUploadHandle() {
      new QiniuJsSDK().uploader( {
        runtimes: 'html5,flash,html4', // 上传模式,依次退化
        browse_button: 'image-handle-upload', // 上传选择的点选按钮，**必需**
        uptoken_url: FILEUPLOAD.GET_IMG_UPTOKEN, // Ajax 请求 uptoken 的 Url，**强烈建议设置**（服务端提供）
        get_new_uptoken: false, // 设置上传文件的时候是否每次都重新获取新的 uptoken
        domain: constants.qiniuDomainImg, // bucket 域名，下载资源时用到，**必需**
        max_file_size: constants.imageMaxSize, // 最大文件体积限制
        flash_swf_url: 'path/of/plupload/Moxie.swf', //引入 flash,相对路径
        max_retries: 0, // 上传失败最大重试次数
        dragdrop: true, // 开启可拖曳上传
        chunk_size: constants.imageMaxSize, // 分块上传时，每块的体积
        auto_start: true, // 选择文件后自动上传，若关闭需要自己绑定事件触发上传,
        multi_selection: false, // 是否多选
        filters: {
          mime_types: [ {
            title: 'Image files',
            extensions: 'jpg,jpeg,png,gif,bmp'
          } ]
        },
        init: {
          Key: function( up, file ) {
            var name = file.name;
            var ext = name.split( '.' );
            var key = constants.userLogin + '_' + ( new Date().getTime() ) + parseInt( Math.random() * 100 ) + '.' + ext[ 1 ];
            return key;
          }
        }
      } );
    }
  },
  mounted() {
    $( '.selectpicker', this.$el ).selectpicker();
    $( '[data-toggle="tooltip"]', this.$el ).tooltip( {
      container: 'body',
    } );
    this.getImgInfo();

    // 确定或取消
    $( this.$el ).on( 'click', '#crop-sure', () => {

      this.imgHandleParam.crop = this.$cropperImg.cropper( 'getData' );
      this.saveStep();
      this.cropHandle();
    } ).on( 'click', '#crop-cancel', () => {
      this.catchCrop = null;
      this.cropHandle();
    } );

    this.qiniuUploadHandle();
  },
  components: {
    slider
  }
}

</script>
<style src="./style.less" lang="less"></style>
